<?php

namespace app\models;

use app\common\Helpers;
use app\components\exceptions\InvalidRequestException;
use Yii;
use yii\helpers\Url;
use yii\web\IdentityInterface;

/**
 * This is the model class for table "{{%admin}}".
 *
 * @property int $id
 * @property string $name 登录名称
 * @property string $password 密码，md5加密成32位密码
 * @property string $email 邮箱
 * @property string $last_login_time 上次登录时间
 * @property int $last_login_ip 上次登录ip
 * @property string $created_at 创建时间
 */
class Admin extends \yii\db\ActiveRecord implements IdentityInterface
{


    const ADMIN_LOGIN_KEY='admin';//后台用户登录session标识
    const SCENARIO_LOGIN = 'login';//登录
    const SCENARIO_SEEK_PASS = 'seekPass';//找回密码，发送邮件
    const SCENARIO_CHANGE_PASS = 'changePass';//修改密码
    const SCENARIO_STORE = 'storeAdmin';//保存用户
    const SCENARIO_UPDATE='updateAdmin';//更新用户
    const SCENARIO_UPDATE_PASS ='updatePassword';//更新密密码
    const TOKEN_ENCRYPT='yii_shop';
    public $repass;
    public $new_password;

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%admin_manager}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['id','required','message'=>'id不能为空','on'=>[
                self::SCENARIO_UPDATE,
                self::SCENARIO_UPDATE_PASS]
            ],
            ['name','required','message'=>'账号不能为空','on'=>[
                self::SCENARIO_LOGIN,
                self::SCENARIO_SEEK_PASS,
                self::SCENARIO_CHANGE_PASS,
                self::SCENARIO_STORE]
            ],
            ['name','validateAdminExist','message'=>'用户名已经存在','on'=>[
                self::SCENARIO_STORE]
            ],
            ['mobile','required','message'=>'手机号不能为空','on'=>[
                self::SCENARIO_STORE,
                self::SCENARIO_UPDATE]
            ],
            ['password','required','message'=>'密码不能为空','on'=>[
                self::SCENARIO_LOGIN,
                self::SCENARIO_CHANGE_PASS,
                self::SCENARIO_STORE,
                self::SCENARIO_UPDATE_PASS]
            ],
            ['password','validatePass','on'=>[
                self::SCENARIO_LOGIN]
            ],
            ['new_password','required','on'=>[
                self::SCENARIO_UPDATE_PASS]
            ],
            ['email','required','message'=>'邮箱不能为空','on'=>[
                self::SCENARIO_SEEK_PASS,
                self::SCENARIO_STORE,
                self::SCENARIO_UPDATE]
            ],
            ['email','email','message'=>'邮箱格式不正确','on'=>[
                self::SCENARIO_SEEK_PASS,
                self::SCENARIO_STORE,
                self::SCENARIO_UPDATE]
            ],
            ['email','validateEmail','on'=>[
                self::SCENARIO_SEEK_PASS]
            ],
            ['repass','required','message'=>'确认密码不能为空','on'=>[
                self::SCENARIO_CHANGE_PASS]
            ],
            ['repass','compare','compareAttribute'=>'password','message'=>'两次密码输入不一致','on'=>[
                self::SCENARIO_CHANGE_PASS]
            ]
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Name',
            'password' => 'Password',
            'mobile'=>'Mobile',
            'email' => 'Email',
            'last_login_time' => 'Last Login Time',
            'last_login_ip' => 'Last Login Ip',
            'created' => 'Created At',
        ];
    }

    /**
     * 登录用户名和密码验证
     *
     */
    public function validatePass()
    {
        if($this->hasErrors()) return;
        if(!$user=self::findOne(['name'=>$this->name])) throw new InvalidRequestException(1010);


        if(!password_verify($this->password,$user->password)){
            throw new InvalidRequestException(1007);
        }

    }

    /**
     * 检查用户名和邮箱是否匹配
     */
    public function validateEmail()
    {
        if($this->hasErrors()) return;

        !self::findOne(['name'=>$this->name,'email'=>$this->email]) && $this->addError('email','邮箱和用户名不匹配');
    }

    /**
     * 检查用户是否已经存在
     */
    public function validateAdminExist()
    {
        //已经有错误了，则不进行验证了
        if($this->hasErrors())return;

        //查找用户名是否已经存在
        self::findOne(['name'=>$this->name]) && $this->addError('name','用户名已被使用');
    }

    /**
     * 找回密码，发送邮件
     */
    public function seekPass($data)
    {
        $this->scenario=self::SCENARIO_SEEK_PASS;//找回密码场景
        $this->checkData($data);

        //获取邮件对象
        $mail= Yii::$app->mailer->compose();

        //发送给谁
        $mail->setTo($this->email);
        $time=time();

        //设置发送的内容
        $mail->setHtmlBody("<a href='".Yii::$app->request->hostInfo.Url::to([
            'public/change-pass-by-email',
                'timestamp'=>$time,
                'name'=>$this->name,
                'token'=>$this->createToken($this->name,$time)
            ])."'>点击链接修改密码</a>");    //发布可以带html标签的文本

        //邮件发送结果
        if($mail->send()){
            Yii::$app->session->setFlash('info','发送邮件成功');
            return true;
        }else{
            Yii::$app->session->setFlash('info','发送邮件失败');
            return false;
        }
    }

    /**
     * 生成token
     */
    public function createToken($name,$time)
    {
        return md5($name.self::TOKEN_ENCRYPT.$time);
    }

    /**
     * 重置密码
     */
    public function changePass($data)
    {
        $this->scenario=self::SCENARIO_CHANGE_PASS;//找回密码场景
        $this->checkData($data);
        $res=self::updateAll([
            'password'=>password_hash($this->password,PASSWORD_DEFAULT),
        ],['name'=>$this->name]);
        return $res?true:false;
    }


    /**
     * 获取登录用户信息，或者失败会导向登录页面
     * $redirect =true 表示需要跳转到登录页面
     */
    public static function getLoginUserInfo($redirect=true)
    {
        $session=Yii::$app->session;
        if(empty($session[self::ADMIN_LOGIN_KEY])){
            if($redirect){
                Yii::$app->runController('admin/public/signin');
            }else{
                return false;
            }
        }else{
            return $session[self::ADMIN_LOGIN_KEY];
        }
    }

    /**
     * 创建一个后台用户
     */
    public function storeAdmin($data)
    {
        $this->scenario=self::SCENARIO_STORE;//登录场景
        $this->checkData($data);

        $this->password=password_hash($this->password,PASSWORD_DEFAULT);
        $this->updated=time();
        $this->created=time();

        //保存数据
        !$this->save() && ExceptionHandler::throwCode(1002);

    }

    /**
     * 删除一个后台用户
     */
    public function delAdmin($id)
    {
        !$id && ExceptionHandler::throwCode(1001);

        !($user=self::findOne(['id'=>$id])) &&　Exception::throwCode(1004);
        !$user->delete() && ExceptionHandler::throwCode(1005);
    }

    /**
             更新后台用户数据
     */
    public function updateAdmin($data)
    {
        $this->scenario=self::SCENARIO_UPDATE;

        $this->checkData($data);
        !($user=self::findOne($this->id)) && ExceptionHandler::throwCode(1004);

        $user->mobile=$this->mobile;
        $user->email=$this->email;
        $user->updated=time();

        !$user->update() && ExceptionHandler::throwCode(1006);

    }

    /**
     * 更新用户手机号
     */
    public function updatePassword($data)
    {
        $this->scenario=self::SCENARIO_UPDATE_PASS;
        $this->checkData($data);

        !($user=self::findOne($this->id)) && ExceptionHandler::throwCode(1004);

        !(password_verify($this->password,$user->password)) && ExceptionHandler::throwCode(1007);

        $user->password=password_hash($this->new_password,PASSWORD_DEFAULT);

        !($user->update()) && ExceptionHandler::throwCode(1008);
    }

    /**
     * 通过用户名获取用户
     * @param $name
     * @return Admin|null
     */
    public static function findByUsername($name)
    {
        return self::findOne(['name' => $name]);
    }


    public static function findIdentity($id)
    {
        return self::findOne($id);
    }

    public static function findIdentityByAccessToken($token, $type = null)
    {
        // TODO: Implement findIdentityByAccessToken() method.
    }

    public function getId()
    {
        return $this->id;
    }

    public function getAuthKey()
    {
        // TODO: Implement getAuthKey() method.
    }

    public function validateAuthKey($authKey)
    {
        // TODO: Implement validateAuthKey() method.
    }

}
